#
#    Pixel War (Cliente) - Cliente de Juego Multiplayer Online
#    Copyright (C) 2010 - Francisco Rivera
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

import select
import socket
import threading
from protocolo import Protocolo
from bala import Bala
from criaturas import Jugador, Principal, HandlerCriaturas
from enviar import Enviar
from mapa import Mapa
from tools import JThread
from score import Score

DEBUG = False

class Conexion:

    PORT = 20000
    
    def __init__(self):        
        self.cliente = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    def conectar(self, juego, host, equipo):        
        try:
            self.cliente.connect((host, Conexion.PORT))
            conectado = True
        except:
            conectado = False
        
        if conectado:
            print "Conexion exitosa"
            Recibir(self.cliente, juego)
            prot = Protocolo()
            prot.enviarDatos(equipo)
            return True            
        else:
            print "Conexion Fallida. No se pudo conectar al host", host
            return False

        
class Recibir(threading.Thread):
    ''' Clase que ejecuta las acciones del cliente de acuerdo a los mensajes '''
        
    def __init__(self, cliente, juego):
        threading.Thread.__init__(self)
        Enviar.SOCKET = cliente
        self.score = Score()
        self.cliente = cliente
        self.juego = juego
        self.hcriat = HandlerCriaturas()
        self.mi_id = None
        self.start()
    
    def run(self):
        while JThread.JUGANDO:
            (rlist, wlist, xlist) = select.select([self.cliente], [], [], .9)
            if rlist != []:
                paquetes = str(self.cliente.recv(1024))
                paquetes = paquetes.split('||')
                for p in paquetes:
                    if p:
                        self.procesar(p)
        self.cliente.close()
        print 'Desconectado del server'
        
    def procesar(self, paquete):
        if DEBUG: print 'Paquete recibido:', paquete
        paquete = paquete.split('|')
        accion = paquete[0]
        mensaje = paquete[1:]
        
        ## listado de paquetes
        if accion == "id":
            # setiamos el id de nuestro jugador
            self.mi_id = int(mensaje[0])
            
        elif accion == 'cr':
            # creamos el objeto
            self.crear(mensaje)
            
        elif accion == 'cv':
            # creamos los objetos
            self.crear_varios(mensaje)
            
        elif accion == 'mp':
            # generamos el mapa
            self.crearMapa(mensaje[0])
            
        elif accion == 'mv':
            # movemos el objeto
            id = int(mensaje[0])
            criat = self.hcriat.getCriaturaById(id)
            if criat:
                x = int(mensaje[1])
                y = int(mensaje[2])
                self.mapa.moverCriatura(criat, x, y)
                criat.mover(x, y)
            
        elif accion == 'er':
            # error
            id = int(mensaje[0])
            self.error(id)            
            
        elif accion == 'dp':
            # disparo
            id = int(mensaje[0])
            dir = mensaje[1]
            x = int(mensaje[2])
            y = int(mensaje[3])
            jug = self.hcriat.getCriaturaById(id)
            if jug:
                self.juego.agregarBala(Bala(id, x, y, dir, jug.getEquipo(), self.juego))
            
        elif accion == 'ht':
            # hit
            id = int(mensaje[0])
            danio = int(mensaje[1])
            jugador = self.hcriat.getCriaturaById(id)
            if jugador:
                jugador.hit(danio)
                
        elif accion == 'dc':
            # desconectar
            id = int(mensaje[0])
            jug = self.hcriat.getCriaturaById(id)
            if jug:
                self.mapa.limpiarPos(jug.x, jug.y)
                self.hcriat.delCriaturaById(id)
            
        elif accion == 'dl':
            # deletear
            id = int(mensaje[0])
            jug = self.hcriat.getCriaturaById(id)
            if jug:
                jug.matar()               
            
        elif accion == 'ok':
            # a daos por el culo cabrones!
            self.juego.comenzar()
            
        elif accion == 'nr':
            # nueva ronda
            score_azul = int(mensaje[0])
            score_rojo = int(mensaje[1])
            ronda = int(mensaje[2])
            self.score.set(score_azul, score_rojo, ronda)
            self.hcriat.resetTodos()
            
        elif accion == 'np':
            # nuevas posiciones de todos los jugadores
            for i in range(0, len(mensaje), 3):
                id = int(mensaje[i])
                px = int(mensaje[i+1])
                py = int(mensaje[i+2])
                jug = self.hcriat.getCriaturaById(id)
                if jug:
                    jug.mover(px, py)            
                    
        else:
            print "Paquete desconocido:", accion
            
        
    def crear(self, mensaje):        
        id = int(mensaje[0])
        equipo = mensaje[1]
        x = int(mensaje[2])
        y = int(mensaje[3])
        vida = int(mensaje[4])
        vida_max = int(mensaje[5])
        if self.mi_id and id == self.mi_id:
            j = Principal(id, x, y, vida, vida_max, equipo)
            self.juego.setPrincipal(j)
        else:
            j = Jugador(id, x, y, vida, vida_max, equipo)
        self.hcriat.addJugador(j)
        self.mapa.setCriatura(j, j.x, j.y)
        print 'jugador creado:', id, "en:", x, y
        
    def crear_varios(self, mensaje):       
        CANT_ARGS = 6
        cant = int(mensaje[0])
        mensaje = mensaje[1:]
        for i in range(0, cant * CANT_ARGS, CANT_ARGS):
            self.crear(mensaje[i:])
        # listo el pollo
        Protocolo().enviarOK()
        
    def error(self, id):    
        if DEBUG: print "Error:", id
        if id == 1:
            pass
        elif id == 2:
            print "No hay posiciones libres. Intente nuevamente mas tarde."            
        
    def crearMapa(self, sec_mapa):
        self.mapa = Mapa(sec_mapa)
        self.juego.pantalla.setMapa(self.mapa)
        